/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.yihu.wlyy.service.app.consult;

import java.util.*;

import com.yihu.wlyy.entity.*;
import com.yihu.wlyy.entity.consult.Consult;
import com.yihu.wlyy.entity.consult.ConsultTeam;
import com.yihu.wlyy.entity.consult.ConsultTeamDoctor;
import com.yihu.wlyy.entity.consult.ConsultTeamLog;
import com.yihu.wlyy.entity.doctor.Doctor;
import com.yihu.wlyy.entity.doctor.DoctorTeam;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.repository.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;
import org.springside.modules.utils.Clock;

import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.MessageType;

/**
 * 網絡諮詢类.
 * 
 * @author George
 */
// Spring Service Bean的标识.
@Component
@Transactional(rollbackFor = Exception.class)
public class ConsultTeamService extends ConsultService {

	private Clock clock = Clock.DEFAULT;

	// 咨询详细记录
	@Autowired
	private ConsultTeamLogDao consultTeamLogDao;
	@Autowired
	private ConsultTeamDoctorDao consultTeamDoctorDao;
	@Autowired
	private SignFamilyDao signFamilyDao;
	@Autowired
	private DoctorPatientDao doctorPatientDao;
	@Autowired
	private DoctorTeamDao doctorTeamDao;
	@Autowired
    private ConsultTeamDao consultTeamDao;
	@Autowired
	private DrHealthTeamMemberDao doctorTeamDoctor;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	/**
	 * 查询患者是否还有未结束的三师咨询
	 * @param patient
	 * @return
	 */
	public boolean exist(String patient,Integer type) {
		int count = consultTeamDao.countByPatient(patient, type);
		return count > 0;
	}

	/**
	 * 查詢醫生網絡諮詢列表
	 * @param type 咨询类型：1、咨询我的，2、公共的， 3、参与过的，4、已结束的
	 * @param id
	 * @param pagesize 每页显示数，默认为10
	 * @return
	 */
	public Page<ConsultTeam> findByDoctor(String uid, int type, long id, int pagesize) {
		if (id < 0) {
			id = 0;
		}
		if (pagesize <= 0) {
			pagesize = 10;
		}
		switch (type) {
		case 0:
			// 全部
			return findByDoctorType0(uid, id, pagesize);
		case 1:
			// 咨询我的
			return findByDoctorType1(uid, type, id, pagesize);
		case 2:
			// 我感兴趣的
			return findByDoctorType2(uid, type, id, pagesize);
		case 3:
			// 我回复的
			return findByDoctorType3(uid, id, pagesize);
		case 4:
			// 已完成的
			return findByDoctorType4(uid, id, pagesize);
		}
		return null;
	}

	/**
	 * 查询全部咨询记录
	 * @param uid
	 * @param id
	 * @param pagesize
	 * @return
	 */
	public Page<ConsultTeam> findByDoctorType0(String uid, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		if (id > 0) {
			return consultTeamDao.findDoctorList(uid, id, pageRequest);
		} else {
			return consultTeamDao.findDoctorList(uid, pageRequest);
		}
	}

	/**
	 * 指定医生三师咨询列表查询
	 * @param uid 医生标识
	 * @param type 咨询类型：1、咨询我的，2、公共的， 3、参与过的，4、已结束的
	 * @param pagesize
	 * @return
	 */
	public Page<ConsultTeam> findByDoctorType1(String uid, int type, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		if (id > 0) {
			return consultTeamDao.findDoctorPointList(uid, id, pageRequest);
		} else {
			return consultTeamDao.findDoctorPointList(uid, pageRequest);
		}
	}

	/**
	 * 公共三师咨询列表查询
	 * @param uid 医生标识
	 * @param type 咨询类型：1、咨询我的，2、公共的， 3、参与过的，4、已结束的
	 * @param pagesize
	 * @return
	 */
	public Page<ConsultTeam> findByDoctorType2(String uid, int type, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);

		// 设置查询条件
		Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
		// 未指定医生
		filters.put("type", new SearchFilter("type", Operator.EQ, 0));
		if (id > 0) {
			filters.put("id", new SearchFilter("id", Operator.LT, id));
		}
		// 未回复
		filters.put("status", new SearchFilter("status", Operator.EQ, 0));
		// 未作废
		filters.put("del", new SearchFilter("del", Operator.EQ, "1"));
		Specification<ConsultTeam> spec = DynamicSpecifications.bySearchFilter(filters.values(), ConsultTeam.class);

		return consultTeamDao.findAll(spec, pageRequest);
	}

	/**
	 * 医生参与过的未结束的三师咨询列表查询
	 * @param uid
	 * @param pagesize
	 * @return
	 */
	public Page<ConsultTeam> findByDoctorType3(String uid, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		if (id > 0) {
			return consultTeamDao.findDoctorJoinList(uid, id, pageRequest);
		} else {
			return consultTeamDao.findDoctorJoinList(uid, pageRequest);
		}
	}

	/**
	 * 医生参与过的已结束的三师咨询列表查询
	 * @param uid
	 * @param pagesize
	 * @return
	 */
	public Page<ConsultTeam> findByDoctorType4(String uid, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		if (id > 0) {
			return consultTeamDao.findDoctorFinishList(uid, id, pageRequest);
		} else {
			return consultTeamDao.findDoctorFinishList(uid, pageRequest);
		}
	}

	/**
	 * 网络咨询咨询日志查询
	 * @param consult 咨询标识
	 * @param pagesize 每页显示数，默认为10
	 * @return
	 */
	public Page<ConsultTeamLog> findLogByConsult(String consult, long id, int pagesize) {
		if (id < 0) {
			id = 0;
		}

		// 设置查询条件
		Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
		filters.put("consult", new SearchFilter("consult", Operator.EQ, consult));

		if (id > 0) {
			if(pagesize>0)
				filters.put("id", new SearchFilter("id", Operator.LT, id));
			else
				filters.put("id", new SearchFilter("id", Operator.GT, id));
		}
		filters.put("del", new SearchFilter("del", Operator.EQ, "1"));
		Specification<ConsultTeamLog> spec = DynamicSpecifications.bySearchFilter(filters.values(), ConsultTeamLog.class);

		if(pagesize <= 0){
			Page<ConsultTeamLog> p = new PageImpl<>(consultTeamLogDao.findAll(spec));
			return p;
		}
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		return consultTeamLogDao.findAll(spec, pageRequest);
	}

	/**
	 * 批量回复
	 * @param logs
	 * @return
	 */
	public void reply(List<ConsultTeamLog> logs, String patient) {
		for (ConsultTeamLog log : logs) {
			reply(log, patient, null, log.getType());
		}
	}

	/**
	 * 添加咨询记录
	 * @param log 日志对象
	 * @param type 类型，0问，1回复，2追问，3评价
	 * @return
	 */
	public ConsultTeamLog reply(ConsultTeamLog log, String patient, String teamOrDoctor, int type) {
		log.setCzrq(clock.getCurrentDate());
		// 保存咨询记录
		ConsultTeamLog temp = consultTeamLogDao.save(log);
		if (temp != null) {
			// 发送消息
			if (type == 1) {
				// 医生回复，给患者发消息
				// sendMessage(patient, teamOrDoctor, "三师咨询", log.getDoctorName() + "回复了您的咨询", log.getConsult(), 214, 1, 0, 0);
				// 患者未读数量+1
				consultTeamDao.increasePatientRead(log.getConsult());
				// 医生有回复
				consultTeamDoctorDao.updateReply(log.getConsult(), teamOrDoctor);
			} else if (type == 0 || type == 2) {
				// 查询相关联的医生
				Iterable<ConsultTeamDoctor> iterable = consultTeamDoctorDao.findByConsult(log.getConsult());
				if (iterable != null && iterable.iterator() != null && iterable.iterator().hasNext()) {
					Iterator<ConsultTeamDoctor> iterator = iterable.iterator();
					while (iterator.hasNext()) {
						// 患者提问或追问，给医生发消息
						ConsultTeamDoctor ctd = iterator.next();
						if (ctd == null) {
							continue;
						}
						// 推送消息给医生
						PushMsgTask.getInstance().put(ctd.getTo(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM_REPLY.D_CT_02.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM_REPLY.指定咨询.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM_REPLY.您有新的消息.name(), temp.getConsult());
					}
				}
				// 医生未读数量+1
				consultTeamDao.increaseDoctorRead(log.getConsult());
			}
		}
		return temp;
	}

	/**
	 * 添加三师咨询
	 * @param ct 三师咨询对象
	 * @param patient 患者标识
	 * @return
	 * @throws Exception
	 */
	public int addTeamConsult(ConsultTeam ct, String patient) throws Exception {
		// 咨询三师
		if (ct.getType() == 1) {
			// 查询三师签约信息
			SignFamily sc = signFamilyDao.findBySanshiPatientYes(patient);
			if (sc == null) {
				// 不存在三师签约
				return -2;
			}
			ct.setTeam(sc.getTeamCode());
			// 设置健康管理师，三师咨询默认给健康管理师处理
			//查找病人所在的团队
			DoctorTeam doctorTeam=doctorTeamDao.findBySanshiParientCode(patient);
			//得到团队的健康管理师
			DrHealthTeamMember drHealthTeamMember = doctorTeamDoctor.findDoctorSanshi2ByTeam(doctorTeam.getCode(),3);
			// 设置家庭医生
			ct.setDoctor( drHealthTeamMember.getMemberCode());
		} else if (ct.getType() == 2) {
			// 咨询家庭医生
			SignFamily sf = signFamilyDao.findByjiatingPatient(patient);
			if (sf == null) {
				// 不存在家庭签约
				return -1;
			}
			// 设置健康管理师，家庭医生咨询默认给健康管理师处理
			//查找病人所在的团队
			DoctorTeam doctorTeam=doctorTeamDao.findByParientCode(patient);
			//得到团队的健康管理师
			DrHealthTeamMember drHealthTeamMember = doctorTeamDoctor.findDoctorJiating2ByTeam(doctorTeam.getCode(),3);
			// 设置家庭医生
			ct.setDoctor( drHealthTeamMember.getMemberCode());
		}
		// 设置患者信息
		ct.setPatient(patient);
		// 查询患者信息
		Patient tempPatient = patientDao.findByCode(patient);
		// 设置患者姓名
		ct.setName(tempPatient.getName());
		// 设置患者生日
		ct.setBirthday(tempPatient.getBirthday());
		//新增性别
		ct.setSex(tempPatient.getSex());
		// 设置患者头像
		ct.setPhoto(tempPatient.getPhoto());
		// 设置操作日期
		ct.setCzrq(new Date());
		ct.setDel("1");
		ct.setStatus(0);
		// 医生未读数量为1
		ct.setDoctorRead(1);
		// 添加咨询记录
		Consult consult = addConsult(ct.getPatient(), null, ct.getSymptoms(), ct.getImages(), ct.getType());
		// 设置咨询标识
		ct.setConsult(consult.getCode());
		// 保存医生咨询信息
		if (consultTeamDao.save(ct) == null) {
			throw new Exception("保存失败！");
		}
		// 添加咨询转发记录
		ConsultTeamDoctor cd = new ConsultTeamDoctor();
		cd.setConsult(consult.getCode());
		cd.setDel("1");
		cd.setCzrq(new Date());
		cd.setTo(ct.getDoctor());
		consultTeamDoctorDao.save(cd);
		// 添加医生咨询日志
		addLogs(ct);
		return 1;
	}

	/**
	 * 添加三师咨询日志
	 * @param ct
	 * @throws Exception
	 */
	private void addLogs(ConsultTeam ct) throws Exception {
		List<ConsultTeamLog> logs = new ArrayList<ConsultTeamLog>();
		// 添加问题咨询日志
		String content = "发病时间：" + (StringUtils.isEmpty(ct.getWhen()) ? "无" : ct.getWhen());
		content += "<br>主要症状：" + (StringUtils.isEmpty(ct.getSymptoms()) ? "无" : ct.getSymptoms());
		// 生成提问日志，并推送相关消息
		ConsultTeamLog infoLog = new ConsultTeamLog();
		infoLog.setConsult(ct.getConsult());
		infoLog.setContent(content);
		infoLog.setDel("1");
		infoLog.setType(0);
		infoLog.setChatType(1);
		infoLog.setCzrq(new Date());
		logs.add(infoLog);
		// 图片日志
		if (StringUtils.isNotEmpty(ct.getImages())) {
			String[] images = ct.getImages().split(",");
			for (String image : images) {
				if (StringUtils.isNoneEmpty(image)) {
					ConsultTeamLog imgLog = new ConsultTeamLog();
					// 设置咨询标识
					imgLog.setConsult(ct.getConsult());
					// 设置图片URL
					imgLog.setContent(image);
					imgLog.setDel("1");
					infoLog.setType(0);
					imgLog.setCzrq(new Date());
					// 图片类型
					imgLog.setChatType(2);
					// 添加到待保存队列
					logs.add(imgLog);
				}
			}
		}
		// 语音日志
		if (StringUtils.isNotEmpty(ct.getVoice())) {
			ConsultTeamLog voiceLog = new ConsultTeamLog();
			// 设置咨询标识
			voiceLog.setConsult(ct.getConsult());
			// 设置语音URL
			voiceLog.setContent(ct.getVoice());
			voiceLog.setDel("1");
			infoLog.setType(0);
			// 语音类型
			voiceLog.setChatType(3);
			voiceLog.setCzrq(new Date());
			// 添加到待保存队列
			logs.add(voiceLog);
		}
		if (!logs.isEmpty()) {
			Iterable<ConsultTeamLog> iterable = consultTeamLogDao.save(logs);
			if (iterable == null || iterable.iterator() == null || !iterable.iterator().hasNext()) {
				// 日志保存失败
				throw new Exception("consult team log save failed!");
			}
		}
		// 患者提问或追问，给医生发消息
		// sendMessage(ct.getDoctor(), ct.getPatient(), "三师咨询", "您有新的三师咨询消息", ct.getConsult(), 116, 1, 0, 0);
	}

	/**
	 * 查询咨询列表
	 * @param patientCode 患者标志
	 * @param status 咨询状态（0未结束，1已结束，-1 已取消）
	 * @param pageSize 页数
	 * @return
	 */
	public Page<ConsultTeam> findByPatient(String patientCode, int status, long id, int pageSize) {
		if (id < 0) {
			id = 0;
		}
		if (pageSize <= 0) {
			pageSize = 10;
		}
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pageSize, sort);

		Page<ConsultTeam> list = null;
		switch (status) {
		case 0:
			// 未结束
			if (id > 0) {
				list = consultTeamDao.findNotFinishedBypatient(patientCode, id, pageRequest);
			} else {
				list = consultTeamDao.findNotFinishedBypatient(patientCode, pageRequest);
			}
			break;
		case 1:
			// 已结束
			if (id > 0) {
				list = consultTeamDao.findFinishedBypatient(patientCode, id, pageRequest);
			} else {
				list = consultTeamDao.findFinishedBypatient(patientCode, pageRequest);
			}
			break;
		case -1:
			// 已取消
			if (id > 0) {
				list = consultTeamDao.findCancelBypatient(patientCode, id, pageRequest);
			} else {
				list = consultTeamDao.findCancelBypatient(patientCode, pageRequest);
			}
			break;
		}
		return list;
	}

	/**
	 * 医生关闭三师咨询
	 * @param consult 三师咨询标识
	 * @return
	 */
	public int finish(String consult) {
		return consultTeamDao.updateStatusByConsult(consult);
	}

	/**
	 * 设置咨询已读
	 *
	 * @param consult
	 * @return
	 */
	public int readMessage(String consult){
        return consultTeamDao.updateReadedByConsult(consult);
	}

	/**
	 * 取消三师咨询
	 * @param consult
	 * @return
	 */
	public int cancel(String consult) {
		return consultTeamDao.cancel(consult);
	}

	public ConsultTeam findByCode(String code) {
		return consultTeamDao.findByConsult(code);
	}

	/**
	 * 三师咨询转接医生
	 * @param from 转出医生标识
	 * @param to 转入医生标识
	 * @param consult 三师咨询标识
	 * @return
	 */
	public void transfer(String from, String to, String consult) {
		// 检查是否存在
		if (consultTeamDoctorDao.isExist(consult, to) == 0) {
			// 查询医生信息
			Doctor d = doctorDao.findByCode(from);
			// 再保存
			ConsultTeamDoctor cd = new ConsultTeamDoctor();
			cd.setConsult(consult);
			cd.setDel("1");
			cd.setCzrq(new Date());
			cd.setFrom(d.getCode());
			cd.setFromName(d.getName());
			cd.setTo(to);
			consultTeamDoctorDao.save(cd);
		}
	}

	/**
	 * 查询患者视频和三师咨询记录
	 * @param patient 患者标识
	 * @param id
	 * @param pagesize
	 * @return
	 */
	public Page<Consult> findConsultRecordByPatientType(String patient, long id, int pagesize) {
		if (pagesize <= 0) {
			pagesize = 10;
		}
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);
		// 设置查询条件
		Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
		filters.put("patient", new SearchFilter("patient", Operator.EQ, patient));
		filters.put("type", new SearchFilter("type", Operator.LT, 3));
		if (id > 0) {
			filters.put("id", new SearchFilter("id", Operator.LT, id));
		}
		// 未作废
		filters.put("del", new SearchFilter("del", Operator.EQ, "1"));
		Specification<Consult> spec = DynamicSpecifications.bySearchFilter(filters.values(), Consult.class);
		return consultDao.findAll(spec, pageRequest);
	}

	/**
	 * 清空医生未读数量
	 * @param consult
	 */
	public void clearDoctorRead(String consult) {
		consultTeamDao.clearDoctorRead(consult);
	}

	/**
	 * 清空患者未读数量
	 * @param consult
	 */
	public void clearPatientRead(String consult) {
		consultTeamDao.clearPatientRead(consult);
	}

	/**
	 * 查询医生的咨询统计
	 *
	 * @param doctorCode
	 * @return
	 */
	public Map<String,Long> getAllCount(String doctorCode) {
		Map<String,Long> result = new HashMap<>();

		//根据医生code查询总咨询数  
		 long allCount=consultTeamDoctorDao.getAllCountByDoctorCode(doctorCode);
		
		//根据医生code查询今日咨询数
		 long todayCount=consultTeamDoctorDao.getTodayCountByDoctorCode(doctorCode);

		result.put("all",allCount);
		result.put("today",todayCount);

		return result;
	}

	/**
	 * 查找未完成咨询
	 *
	 * @param patient
	 * @return
	 */
	public List<ConsultTeam> getUnfinishedConsult(String patient){
		return consultTeamDao.findUnfinishedConsult(patient);
	}

	/**
	 * 查询患者全部的咨询数目
	 * @param patientCode
	 * @return
     */
	public Integer findByDoctorSize(String patientCode,String doctorCode) {

		return consultDao.findByPatient(patientCode,doctorCode);
	}

	public List<Map<String,Object>> getConsultSign(String[] consults){
		String params =  "";
		List<String> paramList = new ArrayList<>();

		for(int i = 0; i < consults.length ; i++){
			params += (i == 0?"?":",?");
		}
		paramList.addAll(Arrays.asList(consults));
		paramList.addAll(Arrays.asList(consults));

		String sqlgp = "select DISTINCT consult,to_doctor from wlyy_consult_team_doctor ctd,wlyy_doctor d where ctd.to_doctor = d.code and d.level = 2 and ctd.consult in (" + params + ") and ctd.del = '1'";
		String sqlgpm = "select DISTINCT to_doctor from wlyy_consult_team_doctor ctd,wlyy_doctor d where ctd.to_doctor = d.code and d.level = 2 and ctd.consult in (" + params + ") and ctd.del = '1'";
		String sqlQu = "select * from wlyy_quota_result where qkdoctor_code in (" + sqlgpm+ ") and quato_code = '1' and level1_type = '1'";
		String sqlQuSum = "select a.consult,sum(ifnull(b.result,0)) sign from ("+ sqlgp +") a left join (" + sqlQu+ ") b on a.to_doctor = b.qkdoctor_code group by a.consult ";

		return jdbcTemplate.queryForList(sqlQuSum,paramList.toArray());
	}

	public ConsultTeamLog oneLog(Long logId) {
		return consultTeamLogDao.findOne(logId);
	}

	public void addFamousTeamConsult(ConsultTeam ct, String uid) throws Exception{
		// 设置患者信息
		ct.setPatient(uid);
		// 查询患者信息
		Patient tempPatient = patientDao.findByCode(uid);
		// 设置患者姓名
		ct.setName(tempPatient.getName());
		// 设置患者生日
		ct.setBirthday(tempPatient.getBirthday());
		//新增性别
		ct.setSex(tempPatient.getSex());
		// 设置患者头像
		ct.setPhoto(tempPatient.getPhoto());
		// 设置操作日期
		ct.setCzrq(new Date());
		ct.setDel("1");
		ct.setStatus(0);
		// 医生未读数量为1
		ct.setDoctorRead(1);
		// 患者未读数量为0
		ct.setPatientRead(0);
		// 添加咨询记录
		Consult consult = addConsult(ct.getPatient(), null, ct.getSymptoms(), ct.getImages(), ct.getType());
		// 设置咨询标识
		ct.setConsult(consult.getCode());
		// 保存医生咨询信息
		if (consultTeamDao.save(ct) == null) {
			throw new Exception("保存失败！");
		}
		// 添加咨询转发记录
		ConsultTeamDoctor cd = new ConsultTeamDoctor();
		cd.setConsult(consult.getCode());
		cd.setDel("1");
		cd.setCzrq(new Date());
		cd.setTo(ct.getDoctor());
		consultTeamDoctorDao.save(cd);
		// 添加医生咨询日志
		addLogs(ct);
	}

	public boolean isExistFamousConsult(String uid) {
		ConsultTeam consultTeam= consultTeamDao.findFamousConsultByPatient(uid);
		if(consultTeam!=null){
			return true;
		}else{
			return false;
		}
	}
}
